1 相关知识
在编译内核之前,首先了解内核启动及 grub 引导菜单的相关知识,了解如何设置修改默认启动内核以及引导菜单中缺失内核的解决方法
(1)查看系统已安装的所有内核
# 查看系统已安装的所有内核
$ ls /boot/vmlinuz-*
/boot/vmlinuz-0-rescue-331f20b322834ebcbe73ee7e21382816
/boot/vmlinuz-6.6.8
/boot/vmlinuz-5.10.0-136.12.0.86.oe2203sp1.x86_64(2)查看安装的内核是否在 grub 引导菜单内
# 查看安装的内核是否在 grub 引导菜单内
$ grep ^menuentry /boot/grub2/grub.cfg
menuentry 'openEuler (6.6.8) 22.03 (LTS-SP1)' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-136.12.0.86.oe2203sp1.x86_64-advanced-dedd25d9-b873-4aff-a832-1594ba77be44' {
menuentry 'openEuler (5.10.0-136.12.0.86.oe2203sp1.x86_64) 22.03 (LTS-SP1)' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-136.12.0.86.oe2203sp1.x86_64-advanced-dedd25d9-b873-4aff-a832-1594ba77be44' {
menuentry 'openEuler (0-rescue-331f20b322834ebcbe73ee7e21382816) 22.03 (LTS-SP1)' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-0-rescue-331f20b322834ebcbe73ee7e21382816-advanced-dedd25d9-b873-4aff-a832-1594ba77be44' {若发现(1)中查找到的内核并没有出现在 grub.cfg 文件中,那么表明在系统启动时,grub 菜单中不会出现该内核选项,即不能启动该内核,此时需要重新生成 grub.cfg 配置文件
# 执行以下命令重新生成 grub.cfg 配置文件
$ grub2-mkconfig -o /boot/grub2/grub.cfg
# 重新生成配置文件后,查看安装的内核是否在 grub 引导菜单内
$ grep ^menuentry /boot/grub2/grub.cfg(3)设置默认启动内核
① 通过内核文件路径设置默认启动内核
# 执行以下命令查看默认启动内核
$ grubby --default-kernel
/boot/vmlinuz-6.6.8
# 执行以下命令设置默认启动内核
$ grubby --set-default /boot/vmlinuz-5.10.0-136.12.0.86.oe2203sp1.x86_64
# 设置完成后,再次查看默认启动内核
$ grubby --default-kernel
/boot/vmlinuz-5.10.0-136.12.0.86.oe2203sp1.x86_64② 通过内核索引设置默认启动内核
# 查看当前所有可启动内核及在 grub 菜单中的索引顺序
$ grubby --info ALL
index=0
kernel=/boot/vmlinuz-6.6.8
args="ro resume=/dev/mapper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap cgroup_disable=files apparmor=0 crashkernel=512M"
root=/dev/mapper/openeuler-root
initrd=/boot/initramfs-6.6.8.img
title=openEuler (6.6.8) 22.03 (LTS-SP1)
index=1
kernel=/boot/vmlinuz-5.10.0-136.12.0.86.oe2203sp1.x86_64
args="ro resume=/dev/mapper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap cgroup_disable=files apparmor=0 crashkernel=512M"
root=/dev/mapper/openeuler-root
initrd=/boot/initramfs-5.10.0-136.12.0.86.oe2203sp1.x86_64.img
title=openEuler (5.10.0-136.12.0.86.oe2203sp1.x86_64) 22.03 (LTS-SP1)
index=2
kernel=/boot/vmlinuz-0-rescue-331f20b322834ebcbe73ee7e21382816
args="ro resume=/dev/mapper/openeuler-swap rd.lvm.lv=openeuler/root rd.lvm.lv=openeuler/swap cgroup_disable=files apparmor=0 crashkernel=512M"
root=/dev/mapper/openeuler-root
initrd=/boot/initramfs-0-rescue-331f20b322834ebcbe73ee7e21382816.img
title=openEuler (0-rescue-331f20b322834ebcbe73ee7e21382816) 22.03 (LTS-SP1)
index=3
non linux entry
index=4
non linux entry
index=5
non linux entry
# 通过索引序号设置默认启动内核
$ grubby --set-default-index=0
# 设置完成后,再次查看默认启动内核
$ grubby --default-kernel
/boot/vmlinuz-6.6.8(4)initramfs 相关命令
# 重新制作 initramfs
$ dracut -f -a lvm --kver=$(uname -r) /boot/initramfs-$(uname -r).img
# 将 initramfs 文件生成到其他位置
$ dracut -f --no-hostonly -output /root/initramfs-xxxx $(uname -r)
# 将额外安装的驱动文件打入 initramfs
$ dracut --no-hostonly --kver=$(uname -r) /boot/initramfs-$(uname -r).img
# 查看 initramfs 文件
$ lsinitrd /boot/initramfs-$(uname -r).img
# 解压 initramfs 文件
$ /usr/lib/dracut/skipcpio /boot/initramfs-$(uname -r).img | zcat | cpio -idmv
# x2openEuler 检查 grubenv 文件
$ grub2-editenv /boot/grub2/grubenv set check=1
$ grub2-editenv /boot/grub2/grubenv unset check2 编译安装内核
以下将以当前的最新的 6.6.8 版本内核为例,在 openEuler 22.03 LTS SP1 操作系统上进行演示
2.1 准备工作
(1)查看当前使用的系统版本及内核版本
# 查看系统版本
$ cat /etc/openEuler-release
openEuler release 22.03 (LTS-SP1)
# 查看内核版本
$ uname -r
5.10.0-136.12.0.86.oe2203sp1.x86_64(2)安装依赖工具
# 安装依赖工具
$ yum install -y \
gcc clang llvm binutils-devel make m4 flex bison patch rpm-build rsync \
audit-libs-devel elfutils-devel elfutils-libelf-devel libcap-devel libcap-ng-devel \
libunwind-devel libzstd-devel numactl-devel openssl-devel zlib-devel xz-devel \
ncurses-devel newt-devel pciutils-devel libbabeltrace-devel dwarves \
python3-devel python3-docutils perl-devel perl-generators \
java-1.8.0-openjdk java-1.8.0-openjdk-devel java-devel \
asciidoc xmlto \
gtk2-devel \
net-tools glibc-static2.2 下载新版本内核
Linux 内核(内核补丁)官网:The Linux Kernel Archives
# 下载内核
$ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.8.tar.xz -P /root
--2023-12-21 15:52:44-- https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.6.8.tar.xz
Resolving cdn.kernel.org (cdn.kernel.org)... 151.101.109.176, 2a04:4e42:1a::432
Connecting to cdn.kernel.org (cdn.kernel.org)|151.101.109.176|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 140076264 (134M) [application/x-xz]
Saving to: ‘/root/linux-6.6.8.tar.xz’
linux-6.6.8.tar.xz 100%[==============================================>] 133.59M 22.7MB/s in 11s
2023-12-21 15:52:58 (12.7 MB/s) - ‘/root/linux-6.6.8.tar.xz’ saved [140076264/140076264]
# 解压内核文件,并更改目录名称
$ tar -Jxvf /root/linux-6.6.8.tar.xz -C /usr/src/kernels/
$ mv /usr/src/kernels/linux-6.6.8 /usr/src/kernels/6.6.82.3 打内核补丁(可选)
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 下载补丁文件
$ wget wget https://cdn.kernel.org/pub/linux/kernel/v6.x/patch-6.6.8.xz
--2023-12-22 10:35:02-- http://wget/
Resolving wget (wget)... failed: Name or service not known.
wget: unable to resolve host address ‘wget’
--2023-12-22 10:35:03-- https://cdn.kernel.org/pub/linux/kernel/v6.x/patch-6.6.8.xz
Resolving cdn.kernel.org (cdn.kernel.org)... 146.75.113.176, 2a04:4e42:8c::432
Connecting to cdn.kernel.org (cdn.kernel.org)|146.75.113.176|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 587540 (574K) [application/x-xz]
Saving to: ‘patch-6.6.8.xz’
patch-6.6.8.xz 100%[==============================================>] 573.77K 317KB/s in 1.8s
2023-12-22 10:35:07 (317 KB/s) - ‘patch-6.6.8.xz’ saved [587540/587540]
FINISHED --2023-12-22 10:35:07--
Total wall clock time: 4.5s
Downloaded: 1 files, 574K in 1.8s (317 KB/s)
# 根据补丁文件压缩类型解压补丁文件
$ xz -dv patch-6.6.8.xz
# 打补丁
$ patch -p1 -i patch-6.6.82.4 生成内核配置文件
生成内核配置文件时有两种方案:
- 重新生成新的内核配置文件
- 基于现有内核配置文件修改
2.4.1 重新生成新的内核配置文件
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 清理以前编译的残留文件(可选)
$ make mrproper
# 执行以下命令修改并生成内核配置文件
$ make menuconfig执行 make menuconfig 命令后,会弹出如下界面,可以勾选需要的功能或模块
- [ ] :按
Y勾选,按N取消勾选 - < > :按
M勾选,按N取消勾选
说明
[ * ] :表示将功能直接编译进内核中,随内核直接在内存中运行
< M > :表示将功能以模块的方式保存在 ROM 中,再调到内存中运行

编辑完成后,点击 <Save>,弹出以下界面

点击 Ok,在新弹出的界面中点击 <Exit> 回到初始界面;在初始界面点击 <Exit> 退出,配置文件便会生成
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 查看生成的配置文件
$ ls -l .config
-rw-r--r-- 1 root root 230696 Dec 21 18:37 .config2.4.2 基于现有内核配置文件修改
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 复制已有内核配置文件
$ cp /boot/config-5.10.0-136.12.0.86.oe2203sp1.x86_64 ./
# 清理以前编译的残留文件(可选)
$ make mrproper
# 执行以下命令修改并生成内核配置文件
$ make menuconfig执行 make menuconfig 命令后,会弹出如下界面

点击 <Load>,弹出以下界面,填写复制过来的配置文件名称

点击 Ok 退出到初始界面,进行进一步修改
- [ ] :按
Y勾选,按N取消勾选 - < > :按
M勾选,按N取消勾选
说明
[ * ] :表示将功能直接编译进内核中,随内核直接在内存中运行
< M > :表示将功能以模块的方式保存在 ROM 中,再调到内存中运行
编辑完成后,点击 <Save>,弹出以下界面

点击 Ok,在新弹出的界面中点击 <Exit> 回到初始界面;在初始界面点击 <Exit> 退出,配置文件便会生成
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 查看生成的配置文件
$ ls -l .config
-rw-r--r-- 1 root root 230696 Dec 21 18:37 .config2.5 编译安装内核
编译安装内核可以分为两种方式:
- 编译源代码后,执行
make install安装 - 编译源代码为 rpm 包,使用
yum安装
说明
这两种方式互不冲突,可以结合使用:即进行了内核源代码编译安装后,仍然可以在编译的基础上,重新编译为 rpm 包;或者直接编译为 rpm 包后,仍然可以直接执行
make modules_install和make install安装
2.5.1 编译后使用 make install 安装
(1)编译内核
编译非常耗时,建议在配置较高的机器上进行,且在 make 时使用 -j 参数指定使用多线程
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 开始编译
$ make -j 12(2)安装内核模块
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 执行以下命令安装内核模块
$ make modules_install -j 12
# 安装内核模块后,会在 /usr/lib/modules/ 目录下创建以内核名称命名的目录,用于存放内核模块
$ tree -L 1 /usr/lib/modules/6.6.8/
/usr/lib/modules/6.6.8/
├── build -> /usr/src/kernels/6.6.8
├── kernel
├── modules.alias
├── modules.alias.bin
├── modules.builtin
├── modules.builtin.alias.bin
├── modules.builtin.bin
├── modules.builtin.modinfo
├── modules.dep
├── modules.dep.bin
├── modules.devname
├── modules.order
├── modules.softdep
├── modules.symbols
└── modules.symbols.bin(3)安装内核
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 执行以下命令安装内核
$ make install
INSTALL /boot
# 安装内核后,会在 /boot 目录产生内核相关文件
$ ls /boot/*6.6.8*
/boot/initramfs-6.6.8.img # 初始化虚拟文件系统
/boot/System.map-6.6.8 # 记录内核中所有符号在内存中中的虚拟地址
/boot/vmlinuz-6.6.8 # 内核文件
# 查看新内核是否被添加到 grub 菜单中
$ grep ^menuentry.*6.6.8 /boot/grub2/grub.cfg
menuentry 'openEuler (6.6.8) 22.03 (LTS-SP1)' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-136.12.0.86.oe2203sp1.x86_64-advanced-dedd25d9-b873-4aff-a832-1594ba77be44' {2.5.2 编译为 rpm 包使用 yum 安装
内核编译完成后,除了执行 make install 安装外,还可以将源代码编译为 rpm 包,方便使用
(1)编译源代码为 rpm 包
# 进入源代码目录
$ cd /usr/src/kernels/6.6.8/
# 执行以下命令编译为 rpm 包
$ make binrpm-pkg -j 12
......
Wrote: /usr/src/kernels/6.6.8/rpmbuild/RPMS/x86_64/kernel-headers-6.6.8-3.x86_64.rpm
Wrote: /usr/src/kernels/6.6.8/rpmbuild/RPMS/x86_64/kernel-6.6.8-3.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.sQCOXi
+ umask 022
+ cd /usr/src/kernels/6.6.8
+ rm -rf /usr/src/kernels/6.6.8/rpmbuild/BUILDROOT/kernel-6.6.8-3.x86_64
+ RPM_EC=0
++ jobs -p
+ exit 0
# 编译完成后,查看生成的 rpm 包(保存在源代码所在目录下的 rpmbuild/RPMS/ 目录中)
$ tree rpmbuild/
rpmbuild/
├── BUILDROOT
├── RPMS
│ └── x86_64
│ ├── kernel-6.6.8-3.x86_64.rpm
│ └── kernel-headers-6.6.8-3.x86_64.rpm
└── SRPMS(2)安装内核 rpm 包
# 使用 yum 安装内核了
$ yum install -y rpmbuild/RPMS/x86_64/kernel-6.6.8-3.x86_64.rpm
# 查看安装后的内核
$ ls /boot/vmlinuz-*
/boot/vmlinuz-0-rescue-331f20b322834ebcbe73ee7e21382816
/boot/vmlinuz-6.6.8
/boot/vmlinuz-5.10.0-136.12.0.86.oe2203sp1.x86_64
# 查看安装的内核模块
$ tree -L 1 /usr/lib/modules/6.6.8/
/usr/lib/modules/6.6.8/
├── kernel
├── modules.alias
├── modules.alias.bin
├── modules.builtin
├── modules.builtin.alias.bin
├── modules.builtin.bin
├── modules.builtin.modinfo
├── modules.dep
├── modules.dep.bin
├── modules.devname
├── modules.order
├── modules.softdep
├── modules.symbols
└── modules.symbols.bin
# 查看新内核是否被添加到 grub 菜单中
$ grep ^menuentry.*6.6.8 /boot/grub2/grub.cfg
menuentry 'openEuler (6.6.8) 22.03 (LTS-SP1)' --class openeuler --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option 'gnulinux-5.10.0-136.12.0.86.oe2203sp1.x86_64-advanced-dedd25d9-b873-4aff-a832-1594ba77be44' {3 启动测试
首先确认安装的新内核是否为默认启动内核
# 执行以下命令查看默认启动内核
$ grubby --default-kernel
/boot/vmlinuz-6.6.8确认默认启动内核是安装的新内核后,重启系统,新内核正常出现在引导菜单中

进入系统,进一步查看内核版本信息
# 查看内核版本信息
$ uname -r
6.6.8
评论